unit fViewer4Win;

interface

uses
  Winapi.Windows,
  Winapi.Messages,
  System.SysUtils,
  System.Variants,
  System.Classes,
  System.DateUtils,
  Vcl.Graphics,
  Vcl.Controls,
  Vcl.Forms,
  Vcl.Dialogs,
  Vcl.ExtCtrls,

  GLS.SceneViewer,
  GLS.AsyncTimer,
  GLS.VectorTypes,
  GLS.BaseClasses,
  GLS.Scene,
  GLS.Objects,
  GLS.Coordinates,
  GLS.GeomObjects,
  GLS.State,
  GLS.Graph,
  GLS.Cadencer;

type
  TForm1 = class(TForm)
    Panel1: TPanel;
    AsyncTimer1: TGLAsyncTimer;
    GLScene1: TGLScene;
    cam: TGLCamera;
    dc_cam: TGLDummyCube;
    GLCube1: TGLCube;
    light1: TGLLightSource;
    dc_light: TGLDummyCube;
    dc_world: TGLDummyCube;
    GLCylinder1: TGLCylinder;
    dc_views: TGLDummyCube;
    cam1: TGLCamera;
    cam2: TGLCamera;
    cam3: TGLCamera;
    GLSphere1: TGLSphere;
    pos_r: TImage;
    pos_t: TImage;
    pos_c: TImage;
    dc_helpers: TGLDummyCube;
    xyz_grid: TGLXYZGrid;
    ViewerXYZ: TGLSceneViewer;
    Shape1: TShape;
    xy_grid: TGLXYZGrid;
    ViewerXY: TGLSceneViewer;
    ViewerXZ: TGLSceneViewer;
    ViewerYZ: TGLSceneViewer;
    yz_grid: TGLXYZGrid;
    xz_grid: TGLXYZGrid;
    procedure FormResize(Sender: TObject);
    procedure AsyncTimer1Timer(Sender: TObject);
    procedure ViewerXZBeforeRender(Sender: TObject);
    procedure ViewerXZAfterRender(Sender: TObject);
    procedure ViewerXYBeforeRender(Sender: TObject);
    procedure ViewerXYAfterRender(Sender: TObject);
    procedure ViewerYZBeforeRender(Sender: TObject);
    procedure ViewerYZAfterRender(Sender: TObject);
    procedure ViewerXYZMouseDown(Sender: TObject; Button: TMouseButton;
      Shift: TShiftState; X, Y: Integer);
    procedure ViewerXYZMouseMove(Sender: TObject; Shift: TShiftState; X, Y: Integer);
    procedure ViewerXYZDblClick(Sender: TObject);
  public
    procedure ShowScene(mv, v1, v2, v3: boolean);
  private
    mx, my: Integer;
  end;

type
  TScnMod = (scnTurn, scnMove);

var
  Form1: TForm1;
  xAlign: single = 0.5;
  yAlign: single = 0.5;
  scnMod: set of TScnMod;

// ==================================================================
implementation
// ==================================================================

{$R *.dfm}

procedure TForm1.FormResize(Sender: TObject);
var
  w, w2, h2: Integer;
begin
  w := clientWidth - Panel1.Width;
  w2 := round((clientWidth - Panel1.Width) * xAlign);
  h2 := round(clientHeight * yAlign);
  ViewerXZ.BoundsRect := rect(3, 3, w2 - 4, h2 - 4);
  ViewerXY.BoundsRect := rect(w2 + 3, 3, w - 4, h2 - 4);
  ViewerYZ.BoundsRect := rect(3, h2 + 3, w2 - 4, clientHeight - 4);
  ViewerXYZ.BoundsRect := rect(w2 + 3, h2 + 3, w - 4, clientHeight - 4);
  Shape1.BoundsRect := rect(w2, h2, w - 1, clientHeight - 1);

  pos_r.BoundsRect := rect(w2 - 4, 3, w2 + 3, clientHeight - 4);
  pos_t.BoundsRect := rect(3, h2 - 4, w - 4, h2 + 3);
  pos_c.BoundsRect := rect(w2 - 4, h2 - 4, w2 + 3, h2 + 3);
end;

procedure TForm1.AsyncTimer1Timer(Sender: TObject);
begin
  if scnMod <> [] then
  begin
    if scnTurn in scnMod then
    begin
    end;
  end;
  GLCube1.Position.Y := Sin(GetTickCount / 1000);
  GLSphere1.Position.Z := Cos(GetTickCount / 600);
  ViewerXYZ.Refresh;
  ViewerXZ.Refresh;
  ViewerXY.Refresh;
  ViewerYZ.Refresh;
end;

procedure TForm1.ShowScene(mv, v1, v2, v3: boolean);
begin
  if not mv then
  begin
    GLCube1.Material.PolygonMode := pmLines;
    GLCylinder1.Material.PolygonMode := pmLines;
    GLSphere1.Material.PolygonMode := pmLines;
    light1.Shining := false;
    xyz_grid.visible := false;
  end
  else
  begin
    GLCube1.Material.PolygonMode := pmFill;
    GLCylinder1.Material.PolygonMode := pmFill;
    GLSphere1.Material.PolygonMode := pmFill;
    light1.Shining := true;
    xyz_grid.visible := true;
  end;
  xz_grid.visible := v1;
  xy_grid.visible := v2;
  yz_grid.visible := v3;
end;

procedure TForm1.ViewerXZBeforeRender(Sender: TObject);
begin
  ShowScene(false, true, false, false);
end;

procedure TForm1.ViewerXZAfterRender(Sender: TObject);
begin
  ShowScene(true, false, false, false);
end;

procedure TForm1.ViewerXYBeforeRender(Sender: TObject);
begin
  ShowScene(false, false, true, false);
end;

procedure TForm1.ViewerXYAfterRender(Sender: TObject);
begin
  ShowScene(true, false, false, false);
end;

procedure TForm1.ViewerYZBeforeRender(Sender: TObject);
begin
  ShowScene(false, false, false, true);
end;

procedure TForm1.ViewerYZAfterRender(Sender: TObject);
begin
  ShowScene(true, false, false, false);
end;

procedure TForm1.ViewerXYZMouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
begin
  mx := X;
  my := Y;
end;

procedure TForm1.ViewerXYZMouseMove(Sender: TObject; Shift: TShiftState;
  X, Y: Integer);
begin
  if Shift <> [] then
    cam.MoveAroundTarget(my - Y, mx - X);
  mx := X;
  my := Y;
end;

procedure TForm1.ViewerXYZDblClick(Sender: TObject);
begin
  ViewerXYZ.Align := alClient;
  ViewerXY.Visible := False;
  ViewerXZ.Visible := False;
  ViewerYZ.Visible := False;
end;


end.
